<p>When using <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock">ReaderWriterLock</a> and <a
href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim">ReaderWriterLockSlim</a> for managing read and write locks,
you should not release a read lock while holding a write lock and vice versa, otherwise you might have runtime exceptions. The locks should be always
correctly paired so that the shared resource is accessed safely.</p>
<p>This rule raises if:</p>
<ul>
  <li> you call <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock">ReaderWriterLock.AcquireWriterLock</a> or <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.upgradetowriterlock">ReaderWriterLock.UpgradeToWriterLock</a>
  and then use <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasereaderlock">ReaderWriterLock.ReleaseReaderLock</a> </li>
  <li> you call <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock">ReaderWriterLockSlim.EnterWriteLock</a> or
  <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock">ReaderWriterLockSlim.TryEnterWriteLock</a> and then use <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitreadlock">ReaderWriterLockSlim.ExitReadLock</a> </li>
  <li> you call <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock">ReaderWriterLock.AcquireReaderLock</a> or <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.downgradefromwriterlock">ReaderWriterLock.DowngradeFromWriterLock</a> and then use <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.releasewriterlock">ReaderWriterLock.ReleaseWriterLock</a> </li>
  <li> or you call <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock">ReaderWriterLockSlim.EnterReadLock</a>, <a
  href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock">ReaderWriterLockSlim.TryEnterReadLock</a>, <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock">ReaderWriterLockSlim.EnterUpgradeableReadLock</a> or <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock">ReaderWriterLockSlim.TryEnterUpgradeableReadLock</a> and then use <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.exitwritelock">ReaderWriterLockSlim.ExitWriteLock</a> </li>
</ul>
<h2>Why is this an issue?</h2>
<p>If you use the <code>ReaderWriterLockSlim</code> class, you will get a <a
href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.lockrecursionexception">LockRecursionException</a>. In the case of
<code>ReaderWriterLock</code>, you’ll get a runtime exception for trying to release a lock that is not owned by the calling thread.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
Public Class Example

    Private Shared rwLock As New ReaderWriterLock()

    Public Sub Writer()
        rwLock.AcquireWriterLock(2000)
        Try
            ' ...
        Finally
            rwLock.ReleaseReaderLock() ' Noncompliant, will throw runtime exception
        End Try
    End Sub

    Public Sub Reader()
        rwLock.AcquireReaderLock(2000)
        Try
            ' ...
        Finally
            rwLock.ReleaseWriterLock() ' Noncompliant, will throw runtime exception
        End Try
    End Sub

End Class
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
Public Class Example

    Private Shared rwLock As New ReaderWriterLock()

    Public Shared Sub Writer()
        rwLock.AcquireWriterLock(2000)
        Try
            ' ...
        Finally
            rwLock.ReleaseWriterLock()
        End Try
    End Sub

    Public Shared Sub Reader()
        rwLock.AcquireReaderLock(2000)
        Try
            ' ...
        Finally
            rwLock.ReleaseReaderLock()
        End Try
    End Sub

End Class
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock">ReaderWriterLock Class</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim">ReaderWriterLockSlim</a> </li>
</ul>

